<?php

namespace LaiHe\LaravelHelper\Eloquent;

use Illuminate\Support\Arr;
use Vinkla\Hashids\Facades\Hashids;

/**
 * @mixin \Illuminate\Database\Eloquent\Builder
 * @mixin \Illuminate\Database\Query\Builder
 */
class Model extends \Illuminate\Database\Eloquent\Model
{
	protected $perPage = 10;

	/**
	 * 查询条件映射:[key => [column, op]]
	 *
	 * @var array
	 */
	protected $paramMaps = [];

	/**
	 * params方法不处理的key
	 *
	 * @var array
	 */
	protected $paramForbids = [];

	/**
	 * 注入查询参数
	 *
	 * @param \Illuminate\Database\Eloquent\Builder $query
	 * @param array                                 $params
	 * @param string|null                           $alias
	 *
	 * @return \Illuminate\Database\Eloquent\Builder|static
	 */
	public function scopeSearchParams($query, array $params = [], $alias = null)
	{
		$alias    = $alias ? $alias . '.' : '';
		$params   = array_filter($params);
		$params   = Arr::except($params, $this->paramForbids);
		$fillable = $this->primaryKey ? array_merge($this->fillable, [$this->primaryKey]) : $this->fillable;
		//其他查询 like >= <= > < ...
		foreach(Arr::only($params, array_keys($this->paramMaps)) as $key => $value){
			$map = $this->paramMaps[$key];
			if($map[1] == 'like'){
				$value = "%$value%";
			}
			$query = $query->where($alias . $map[0], $map[1], $value);
			unset($params[$key]);
		}
		//基础查询 in =
		foreach(Arr::only($params, $fillable) as $key => $value){
			$query = is_array($value) ? $query->whereIn($alias . $key, $value) : $query->where($alias . $key, $value);
			unset($params[$key]);
		}
		if($relations = Arr::get($params, '_with')){
			$relations = is_string($relations) ? explode(',', $relations) : [];
			$query     = $query->with($relations);
		}
		if($relationsCount = Arr::get($params, '_with_count')){
			$relationsCount = is_string($relationsCount) ? explode(',', $relationsCount) : [];
			$query          = $query->withCount($relationsCount);
		}

		return $query;
	}

	/**
	 * @inheritdoc
	 */
	protected function castAttribute($key, $value)
	{
		switch($this->getCastType($key)){
			case 'string':
				return (string)$value;
			case 'url':
				return $value ? url($value) : null;
			case 'image':
				return $value ? asset($value) : null;
			case 'encode':
				return Hashids::encode($value);
			case 'filesize':
				return convertFileSize($value);
			default:
				return parent::castAttribute($key, $value);
		}
	}

	/**
	 * 序列化属性
	 *
	 * @param string $key
	 * @param mixed  $value
	 */
	protected function serializeProperty($key, $value)
	{
		if(!is_array($value) && !is_object($value)){
			$this->attributes[$key] = $value;
		}else{
			$value                  = array_replace_recursive(toArray($this->getAttribute($key)), toArray($value));
			$this->attributes[$key] = serialize($value);
		}
	}

	/**
	 * 混肴键值
	 *
	 * @param string|null $name
	 *
	 * @return string
	 */
	public function encodeValue($name = null)
	{
		return Hashids::encode($this->getAttribute($name ?: $this->getKeyName()));
	}
}